
require("Scripts/Common/Utility")
require("Scripts/Common/Class")
require("Scripts/UISystem/EventDispatcher")

DisplayView = Class(EventDispatcher)

function DisplayView:Ctor()
	self._name = nil					-- 控件的名称
	self._parent = nil					-- 父控件
	self._childs = {}					-- 控件的子控件
	self._show = SailUIDisplayView()	-- 创建显示控件

	self._x = 0					-- 控件的x坐标
	self._y = 0					-- 控件的y坐标
	self._width = 0				-- 控件的宽度
	self._height = 0			-- 控件的高度

	self._alpha = 1				-- 控件自身的alpha
	self._abs_alpha = 1			-- 控件的绝对alpha = 父控件的绝对alpha * 控件自身的alpha

	self._visible = true		-- 控件自身的visible
	self._abs_visible = true	-- 控件的绝对visible = 父控件的绝对visible && 控件自身的visible

	self._disable = false		-- 控件是否禁用
end

-- 获取子控件的索引
function DisplayView:GetChildIndex(child)
	-- 判定child的父控件是否是自己，如果不是则返回无效值0
	if child._parent ~= self then return 0 end
	-- 遍历子控件列表，找到控件所对应的索引
	for k, v in ipairs(self._childs) do
		if v == child then return k end
	end
	-- 没有找到直接返回无效值0
	return 0
end

-- 添加子控件
function DisplayView:AddChild(child)
	-- 判定child的父控件是否是自己，如果不是则返回false
	if child._parent == self then return false end
	-- 判定child是否有父控件，如果有则父控件移除child
	if child._parent then child._parent:RemoveChild(child) end
	-- 把child的父控件设置为自己
	child._parent = self
	-- 把child插入到队首
	table.insert(self._childs, 1, child)
	-- 把child的show添加到自己的show中
	self._show:AddChild(child._show)
	-- 刷新child的一些属性
	child:SetVisible(child._visible)
	child:SetAlpha(child._alpha)
	child:SetDisable(child._disable)
	return true
end

-- 移除子控件
function DisplayView:RemoveChild(child)
	-- 判定child的父控件是否是自己，如果不是则返回false
	if child._parent ~= self then return false end
	-- 移除show
	self._show:RemoveChild(child._show)
	-- 从child队列中移除
	table.remove(self._childs, self:GetChildIndex(child))
	-- child的父控件设置为空
	child._parent = nil
	return true
end

-- 移除所有子控件
function DisplayView:RemoveAll()
	for k, v in ipairs(self._childs) do
		-- 移除show
		self._show:RemoveChild(v._show)
		-- child的父控件设置为空
		v._parent = nil
	end
	self._childs = {}
	return true
end

-- 将子控件移到顶端
function DisplayView:MoveToTop(child)
	-- 判定child的父控件是否是自己，如果不是则返回false
	if child._parent ~= self then return false end
	-- 获取child的索引，如果已经是1就什么都不做
	local child_index = self:GetChildIndex(child)
	if child_index == 1 then return true end
	-- 移除show，再添加show。相当于移到尾部
	self._show:RemoveChild(child._show)
	self._show:AddChild(child._show)
	-- 移除child，再添加child。相当于移到队首
	table.remove(self._childs, child_index)
	table.insert(self._childs, 1, child)
end

-- 设置控件组的x，y坐标
function DisplayView:SetXY(x, y)
	-- 设置当前的x，y坐标
	self._x = x
	self._y = y
	-- 设置show的x，y坐标
	if self._show then
		self._show:SetXY(x, y)
	end
end

-- 由于控件组没有宽高，所以什么都不做
function DisplayView:SetWH(w, h)
	-- 设置当前的x，y坐标
	self._width = w
	self._height = h
	-- 设置show的x，y坐标
	if self._show then
		self._show:SetWH(w, h)
	end
end

-- 获取控件的宽高
function DisplayView:GetWH()
	return self._width, self._height
end

-- 由于控件组没有RGB，所以什么都不做
function DisplayView:SetRGB(red, green, blue)
end

-- 设置alpha值
function DisplayView:SetAlpha(alpha)
	-- 设置控件自身的alpha
	self._alpha = alpha
	-- 计算控件的绝对alpha
	if self._parent then
		self._abs_alpha = self._parent._abs_alpha * alpha
	else
		self._abs_alpha = alpha
	end
	-- 刷新子控件的alpha
	for k, v in pairs(self._childs) do
		v:SetAlpha(v._alpha)
	end
end

-- 设置是否可见
function DisplayView:SetVisible(visible)
	-- 设置控件自身的visible
	self._visible = visible
	-- 设置控件绝对的visible
	if self._parent then
		self._abs_visible = self._parent._abs_visible and visible
	else
		self._abs_visible = visible
	end
	-- 刷新子控件的visible
	if self._show then
		self._show:SetVisible(self._abs_visible)
	end
end

-- 设置是否禁用
function DisplayView:SetDisable(disable)
	-- 设置控件自身的disable
	self._disable = disable
	-- 设置控件绝对的disable
	if self._parent then
		self._abs_disable = self._parent._abs_disable or disable
	else
		self._abs_disable = disable
	end
	-- 刷新子控件的disable
	for k, v in pairs(self._childs) do
		v:SetDisable(v._disable)
	end
end

-- 检查坐标(x, y)是否在控件范围内，返回被点中的控件
function DisplayView:PickUp(x, y)
	-- 检查是否被禁用，是否可见
	if self._abs_disable or self._abs_visible == false then return nil, nil end
	-- 检查是否在当前矩形范围
	if x < self._x or y < self._y or x >= self._width or y >= self._height then return nil, nil end
	-- 计算出相对于控件的点
	local rel_x = x - self._x
	local rel_y = y - self._y
	-- 滚动焦点
	local scroll_control = nil
	if self._can_scroll then scroll_control = self end
	-- 计算点是否在子控件内部
	for k, v in ipairs(self._childs) do
		local v_scroll, v_focus
		-- 获取滚动焦点和移动焦点
		v_scroll, v_focus = v:PickUp(rel_x, rel_y)
		-- 如果有移动焦点，那个可以直接返回
		if v_focus then
			if v_scroll then scroll_control = v_scroll end
			return scroll_control, v_focus
		end
	end
	return scroll_control, self
end
